package junior.db.dao.ext;

import com.google.common.collect.Lists;
import org.springframework.util.Assert;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

public class ExtWrapper {
    /**
     * 需要扩展的实体类
     */
    private Class<?> entityClass;
    /**
     * 扩展字段，值使用插入或更新时传入的Entity实体类的值
     */
    private List<String> extFields;
    /**
     * 扩展字段及值，用于单实体插入或更新
     */
    private Map<String, Object> ext;
    /**
     * 扩展字段及值，用于批量实体插入或更新
     */
    private List<Map<String, Object>> exts;
    
    /**
     * 指定扩展字段
     * @param entityClass
     * @param extFields 不能为空
     * @return
     */
    public static ExtWrapper create(Class<?> entityClass, String...extFields) {
        return new ExtWrapper(entityClass, Arrays.asList(extFields));
    }
    
    /**
     * 指定扩展字段及其值
     *
     * @param entityClass
     * @param ext 不能为空
     * @return
     */
    public static ExtWrapper create(Class<?> entityClass, Map<String, Object> ext) {
        return new ExtWrapper(entityClass, null, ext);
    }
    
    /**
     * <h3>指定扩展字段或指定扩展字段及其值</h3>
     * <b>extFields和ext必须有一个不为null</b>
     * @param entityClass
     * @param extFields
     * @param ext
     * @return
     */
    public static ExtWrapper create(Class<?> entityClass, List<String> extFields, Map<String, Object> ext) {
        return new ExtWrapper(entityClass, extFields, ext);
    }
    
    /**
     * <h3>指定扩展字段和值，用于批量插入或更新</h3>
     * @param entityClass
     * @param exts 不能为空
     * @return
     */
    public static ExtWrapper createBatch(Class<?> entityClass, List<Map<String, Object>> exts) {
        return new ExtWrapper(entityClass, null, exts);
    }
    
    /**
     * <h3>指定扩展字段或指定扩展字段及其值，用于批量插入或更新</h3>
     * <b>extFields和exts必须有一个不为null</b>
     * @param entityClass
     * @param extFields
     * @param exts
     * @return
     */
    public static ExtWrapper createBatch(Class<?> entityClass, List<String> extFields, List<Map<String, Object>> exts) {
        return new ExtWrapper(entityClass, extFields, exts);
    }
    
    private ExtWrapper(Class<?> entityClass, List<String> extFields) {
        Assert.notNull(entityClass, "Parameter entityClass is required");
        Assert.isTrue(extFields != null, "Parameter extFields is required");
        this.entityClass = entityClass;
        this.extFields = extFields;
    }
    
    private ExtWrapper(Class<?> entityClass, List<String> extFields, Map<String, Object> ext) {
        Assert.notNull(entityClass, "Parameter entityClass is required");
        Assert.isTrue(ext != null || extFields != null, "Parameter ext or extFields is required");
        this.entityClass = entityClass;
        this.ext = ext;
        this.extFields = extFields;
        if (this.extFields == null) {
            this.extFields = Lists.newArrayList(ext.keySet());
        }
    }
    
    private ExtWrapper(Class<?> entityClass, List<String> extFields, List<Map<String, Object>> exts) {
        Assert.notNull(entityClass, "Parameter entityClass is required");
        Assert.isTrue(exts != null || extFields != null, "Parameter exts or extFields is required");
        this.entityClass = entityClass;
        this.exts = exts;
        this.extFields = extFields;
        if (this.extFields == null) {
            this.extFields = Lists.newArrayList(ext.keySet());
        }
    }
    
    public Class<?> getEntityClass() {
        return entityClass;
    }
    
    public Map<String, Object> getExt() {
        return ext;
    }
    
    public List<Map<String, Object>> getExts() {
        return exts;
    }
    
    public List<String> getExtFields() {
        return extFields;
    }
    
}
